package com.css.fxfzfxqh.modules.buildingKilometerGrid.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.css.fxfzfxqh.base.response.RestResponse;
import com.css.fxfzfxqh.exceptions.ShpFieldException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.StrategyFactoryException;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.PageResult;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.entity.FxqhBuildingGridDataVersion;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.entity.FxqhBuildingGridFieldDesc;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.param.*;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.vo.FxqhBuildingGridDataVersionPageVo;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.model.vo.ListFileDescByDataTypeVo;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.service.FxqhBuildingGridDataVersionService;
import com.css.fxfzfxqh.modules.population.mode.params.VersionDataExportParam;
import com.css.fxfzfxqh.util.PlatformPageUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.condition.RequestConditionHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.util.*;

/**
 * 建筑物公里网格版本controller
 */
@RestController
@Slf4j
@RequestMapping("buildingGridDataVersion")
public class FxqhBuildingGridDataVersionController {
    @Autowired
    private FxqhBuildingGridDataVersionService fxqhBuildingGridDataVersionService;

    /**
     * 保存新版本
     *
     * @param param
     * @return
     */
    @PostMapping("saveNewVersion")
    public RestResponse<String> saveNewVersion(
            @Validated  @RequestBody FxqhBuildingGridVersionSaveNewDataVersionParam param) {
        try {
            if (param.getDataRangeCountry() == null) {
                return RestResponse.fail("数据范围为空");
            }
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.saveNewVersion(param));
        } catch (BizException v1) {
            log.error(v1.getMessage(), v1);
            return RestResponse.fail(v1.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("新增失败!");
        }
    }

    /**
     * 查询建筑物公里格网版本信息
     *
     * @param versionCode 版本号
     * @return
     */
    @GetMapping("versionCode/{versionCode}")
    public RestResponse<FxqhBuildingGridDataVersion> getByVersionCode(
            @PathVariable("versionCode") String versionCode) {
        try {
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.getByVersionCode(versionCode));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败");
        }
    }

    /**
     * 保存元数据信息
     *
     * @param param
     * @return
     */
    @PostMapping("saveMetaDataInfo")
    public RestResponse saveMetaDataInfo(
            @RequestBody VersionSaveMetaDataParam param) {
        try {
            fxqhBuildingGridDataVersionService.saveMetaDataInfo(param);
            return RestResponse.succeed();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("保存失败!");
        }
    }

    /**
     * 查询元数据信息
     *
     * @param versionCode 版本号
     * @return
     */
    @GetMapping("getMetaDataByVersionCode/{versionCode}")
    public RestResponse getMetaDataByVersionCode(@PathVariable("versionCode") String versionCode) {
        try {
            return RestResponse.succeed(
                    fxqhBuildingGridDataVersionService.getMetaDataByVersionCode(versionCode));
        } catch (Exception e) {
            log.error(e.getMessage(), "错误参数：" + versionCode);
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 获取历史版本号列表接口
     *
     * @return
     */
    @GetMapping("getVersionCodeList/{type}")
    public RestResponse getVersionCodeList(@PathVariable("type") String dataType) {
        return RestResponse.succeed(
                fxqhBuildingGridDataVersionService.getVersionCodeList(dataType));
    }

    /**
     * 覆盖旧版本
     *
     * @param param
     * @return
     */
    @PostMapping("overwriteOldVersion")
    public RestResponse overwriteOldVersion(
            @RequestBody FxqhBuildingGridVersionSaveNewDataVersionParam param) {
        try {
            return RestResponse.succeed(
                    fxqhBuildingGridDataVersionService.overwriteOldVersion(param));
        } catch (BizException v1) {
            return RestResponse.fail(v1.getMessage());
        } catch (Exception v3) {
            log.error(v3.getMessage(), v3);
            return RestResponse.fail("覆盖失败!");
        }
    }

    /**
     * 删除版本
     *
     * @param id 版本id
     * @return
     */
    @GetMapping("del")
    public RestResponse del(String id) {
        try {
            fxqhBuildingGridDataVersionService.delByIds(Collections.singletonList(id));
            return RestResponse.succeed();
        } catch (StrategyFactoryException re) {
            return RestResponse.fail("数据类别有误!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("删除失败");
        }
    }

    /**
     * 分页查询
     *
     * @param fxqhBuildingGridDataVersionPageParam 查询参数
     * @return
     */
    @GetMapping("page")
    public RestResponse<PageResult<FxqhBuildingGridDataVersionPageVo>> page(
            FxqhBuildingGridDataVersionPageParam fxqhBuildingGridDataVersionPageParam) {
        try {
            PageResult<FxqhBuildingGridDataVersionPageVo> page =
                    fxqhBuildingGridDataVersionService.page(fxqhBuildingGridDataVersionPageParam);
            return RestResponse.succeed(page);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 查询，无分页
     *
     * @param fxqhBuildingGridDataVersionPageParam 查询参数
     * @return
     */
    @GetMapping("list")
    public RestResponse<List<FxqhBuildingGridDataVersionPageVo>> list(
            FxqhBuildingGridDataVersionPageParam fxqhBuildingGridDataVersionPageParam) {
        try {
            List<FxqhBuildingGridDataVersionPageVo> list =
                    fxqhBuildingGridDataVersionService.list(fxqhBuildingGridDataVersionPageParam);
            return RestResponse.succeed(list);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 数据导出，将符合条件的数据导出为excel07-xlsx格式
     *
     * @param response
     * @param params：版本数据id列表
     */
    @PostMapping("dataExport")
    public RestResponse dataExport(HttpServletResponse response, VersionDataExportParam params) {
        try {
            fxqhBuildingGridDataVersionService.dataExport(response, params.getIds(), false);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return RestResponse.succeed();
    }

    /**
     * 查询数据视图
     *
     * @param queryByVersionParam 数据视图查询参数
     * @return
     */
    @GetMapping("queryDataView")
    public RestResponse queryDataView(QueryByVersionParam queryByVersionParam) {
        log.debug("buildingGridDataVersion/queryDataView:{}", JSONObject.toJSONString(queryByVersionParam, SerializerFeature.PrettyFormat));
        // 验证数据版本是否为空
        if (!StringUtils.isNotBlank(queryByVersionParam.getVersionCode())) {
            return RestResponse.fail("版本号为必填项!");
        }
        try {
            if (queryByVersionParam.getPage() == null || queryByVersionParam.getPage() < 1) {
                queryByVersionParam.setPage(1);
            }
            if (queryByVersionParam.getRows() == null || queryByVersionParam.getRows() < 1) {
                queryByVersionParam.setRows(10);
            }
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.queryDataVersionByParam(queryByVersionParam));
        } catch (BizException be) {
            log.error(be.getMessage(), be);
            return RestResponse.fail(be.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 查询数据视图
     *
     * @param queryByVersionParam 数据视图查询参数
     * @return
     */
    @GetMapping("getGridDataList")
    public RestResponse getGridDataList(QueryByVersionParam queryByVersionParam) {
        // 验证数据版本是否为空
        if (!StringUtils.isNotBlank(queryByVersionParam.getVersionCode())) {
            return RestResponse.fail("版本号为必填项!");
        }
        try {
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.queryDataVersionByParam(queryByVersionParam));
        } catch (BizException be) {
            log.error(be.getMessage(), be);
            return RestResponse.fail(be.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    @PostMapping("exportDataView")
    public void exportDataView(
            HttpServletResponse response,
            FxqhBuildingGridDataVersionPageParam fxqhBuildingGridDataVersionPageParam) {
        try {
            fxqhBuildingGridDataVersionService.exportDataView(response, fxqhBuildingGridDataVersionPageParam);
        } catch (BizException be) {
            log.error(be.getMessage(), be);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @GetMapping("parseShp")
    public RestResponse parseShp(String fileIds) {
        try {
            if (!fxqhBuildingGridDataVersionService.shpFileAllHasCheck(fileIds)) {
                return RestResponse.fail("shp,cpg,dbf,prj,shx未全部上传或者正在上传中，请上传完成后再继续!");
            }
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.parseShp(fileIds));
        } catch (ShpFieldException sfe) {
            log.error(sfe.getMessage(), sfe);
            return RestResponse.fail(sfe.getMessage());
        } catch (IndexOutOfBoundsException ioobe) {
            log.error(ioobe.getMessage(), ioobe);
            return RestResponse.fail("字段数量不符合要求");
        } catch (StrategyFactoryException sfe) {
            log.error(sfe.getMessage(), sfe);
            return RestResponse.fail(sfe.getMessage());
        } catch (DataIntegrityViolationException dive) {
            log.error(dive.getMessage(), dive);
            return RestResponse.fail("数据类型不匹配");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail(e.getMessage());
        }
    }

    /**
     * 查询字段说明
     *
     * @return
     */
    @GetMapping("getFieldDesc")
    public RestResponse<List<ListFileDescByDataTypeVo>> listFileDescByDataType() {
        try {
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.listFileDescByDataType());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 根据版本号查询建筑物公里网格数据
     *
     * @param param
     * @return
     */
    @GetMapping("queryDataByVersionCode")
    public RestResponse queryDataByVersionCode(
            QueryByVersionParam param) {
        try {
            if (param.getPage() == null || param.getPage() < 1) {
                param.setPage(1);
            }
            if (param.getRows() == null || param.getRows() < 1) {
                param.setRows(10);
            }
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.queryDataVersionByParam(param));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 根据id查询建筑物公里网格数据
     *
     * @param id
     * @return
     */
    @GetMapping("queryDataById")
    public RestResponse queryBuildingGridById(
            String id,
            String typeCode) {
        try {
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.queryBuildingGridById(id, typeCode));
        } catch (StrategyFactoryException v) {
            return RestResponse.fail(v.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 根据id删除建筑物公里网格数据
     *
     * @param id
     * @return
     */
    @GetMapping("delDataById")
    public RestResponse delDataById(
            String id,
            String typeCode) {
        try {
            fxqhBuildingGridDataVersionService.delDataById(id, typeCode);
            return RestResponse.succeed("删除成功!");
        }catch (StrategyFactoryException v) {
            return RestResponse.fail(v.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("删除失败!");
        }
    }

    /**
     * 现场灾害查询版本信息
     *
     * @return
     */
    @RequestMapping("xczh/list")
    public RestResponse<PageResult<FxqhBuildingGridDataVersion>> xczhList(HttpServletRequest request) {
        int current = Integer.valueOf(request.getParameter(PlatformPageUtils.CUR_PAGE));
        int size = Integer.valueOf(request.getParameter(PlatformPageUtils.PAGE_SIZE));
        return RestResponse.succeed(fxqhBuildingGridDataVersionService.xczhList(current, size));
    }

    /**
     * 现场灾害根据版本号查询建筑物公里网格数据
     *
     * @param version
     * @param type
     * @return
     */
    @GetMapping("xczh/listGridDataByVersionCode")
    public RestResponse<?> xczhGet(@RequestParam("version") String version, @RequestParam("type") String type) {
        try {
            return RestResponse.succeed(fxqhBuildingGridDataVersionService.listGridDataByVersionCode(version, type));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return RestResponse.fail("查询失败!");
        }
    }

    /**
     * 导出
     * @param name
     */
    @PostMapping("exportShp")
    public void exportShp(@RequestParam("name") String name,@RequestParam("versionId") String versionId,
                          HttpServletResponse response){
        try {
            fxqhBuildingGridDataVersionService.exportShp(name,versionId,response);
        } catch (Exception e) {
            log.error("导出失败,名字{},id:{}",name,versionId,e.getMessage(),e);
        }
    }
}
